//实现一部日志的缓冲区

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <cassert>
namespace wrtlog{
#define DEFAULT_BUFFER_SIZE (1*1024*1024) 
#define THRESHOLD_BUFFER_SIZE (10*1024*1024)
#define INCREMENT_BUFFER_SIZE (1*1024*1024)
    class Buffer{
        public:
        Buffer():
        _buffer(DEFAULT_BUFFER_SIZE),
        _writer_idx(0),
        _reader_idx(0)
        {}

        void push(const char * data,size_t len)//向缓冲区写入数据
        {
            //缓冲区剩余空间不足：扩容 
            //固定大小则直接返回
            // if(len > writeAblesize()) return ;
            //动态空间用于极限性能测试——扩容
            assert(len <= writeAblesize());
            ensureEnoughSize(len);
            //将数据拷贝进缓冲区
            std::copy(data,data+len,&_buffer[_writer_idx]);
            //将当前写入位置偏移
            _writer_idx+=len;
        }
        const char * begin() //返回可读数据的起始地址
        {
            return &_buffer[_reader_idx];
        }
        size_t readAbleSize()//可读数据长度
        {
            //因为当前实现的并不是循环缓冲区 只会向后写 不会涉及循环利用空间
            return (_writer_idx - _reader_idx);
        }
        size_t writeAblesize(){
            //对于扩容思路 不存子啊可写空间大小 因为总是可写
            //只针针对固定大小缓冲区
            return (_buffer.size() - _writer_idx);
        }
        //对读写指针向后偏移
        size_t moveReader(size_t len){
            assert(len <= readAbleSize());
            _reader_idx+=len;
        }

        void reset()//初始化缓冲区
        {
            //缓冲区的所有空间都是空闲
            _reader_idx=0;
            _writer_idx=0;
        }
        void swap(Buffer&buffer)//对Buffer实现交换
        {
            _buffer.swap(buffer._buffer);
            std::swap(_reader_idx,buffer._reader_idx);
            std::swap(_writer_idx,buffer._writer_idx);
        }
        void pop(size_t len){
            _reader_idx+=len;
            assert(_reader_idx <= _writer_idx);
        }
        bool empty()//判断缓冲区是否为空
        {
            return (_reader_idx == _writer_idx);
        }

        private:
            //对空间进行扩容
            void ensureEnoughSize(size_t len){
                if(len <= writeAblesize()) return ;
                size_t newsize=0;
                if(_buffer.size() < THRESHOLD_BUFFER_SIZE){
                    newsize=_buffer.size()*2+len; //小于阈值成倍增长
                }
                else {
                    newsize=_buffer.size() + INCREMENT_BUFFER_SIZE+len;// 否则线性增长
                }
                _buffer.resize(newsize);
            }
        private:
        std::vector<char> _buffer;
        size_t _reader_idx; //当前可读数据的指针
        size_t _writer_idx; //当前可写数据的指针
    };
}
